package com.mantru.iotpot.modbus;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.text.*;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.mantru.iotpot.modbus.ModbusRtuMaster;

public class ModbusSendThread extends Thread
{
    public boolean Active;     //线程状态
    private List list;         //放自身的消息队列
    private ModbusRtuMaster com;  //串口对象

    //常量
    private byte BUFFER_TYPE_SUBMIT = 2;           //下行包，即将要发给客户端的包
    private byte BUFFER_TYPE_QUIT = 4;             //终止线程


    //构造函数
    public ModbusSendThread(ModbusRtuMaster aCom)
    {
        list = new ArrayList();
        Active = true;
        com = aCom;
        Log("ModbusSendThread create success");
    }


    @Override
    public void run()
    {
        int sleep_time = 0;
        Object obj;
        while (Active)
        {
            try
            {
                obj = GetObject();
                if (obj != null)
                {
                    ModbusSendBuffer data = (ModbusSendBuffer)obj;
                    if (data.buffer != null && data.buffer.length > 0) {
                        com.LastAddress = data.LastAddress;
                        com.LastLength = data.LastLength;
                        com.SequenceNo++;
                        com.Log("串口发送：SequenceNo=" + com.SequenceNo + "，Bytes=" + ByteUtil.toHexString(data.buffer) + com.Decode_SendBuffer(ByteUtil.toHexString(data.buffer)));
                        com.com_send_last_time = Common.GetTimeStamp13();
                        com.com_wait_receive_count++;
                        com.serialHelper.send(data.buffer);
                        data.Dispose();
                        sleep_time = 0;
                    }
                    data = null;
                    Thread.sleep(100);   //黎工说发送间隔要100ms
                    sleep_time += 100;
                }
                else
                {
                    Thread.sleep(20);
                    sleep_time += 20;
                }
                //要求串口每500ms读一次全部地址
                if (sleep_time >= 500 && com.ac.iap_status == 0)
                {
                    sleep_time = 0;
                    //设备自检中，要检查读取0x003B地址，防止因没有回复而错过了自检
                    if (com.ac.DeviceStatus == 1 && com.ac.CheckSelfStatus == 1) {
                        long now = Common.GetTimeStamp13();
                        //超时1秒没回复就要重发
                        if (now - com.ac.CheckSelfStatus_LastTime >= 1000) {
                            com.ac.CheckSelfStatus_LastTime = now;
                            com.ReadHoldingRegister(0x01, 0x003B, 0x0001);
                        }
                    }

                    com.ReadHoldingRegister(0x01, 0x0000, 0x006D);
                }
                if (com.ac.app_is_release == true)
                    Active = false;
            }
            catch (Exception E)
            {
            }
        }

        Log("ModbusSendThread end run");
    }

    private void Log(String value)
    {
        System.out.println("-->" + value);
    }

    //向线程增加要发送的内容
    public void AddSendData(byte[] data, int address, int len)
    {
        ModbusSendBuffer obj = new ModbusSendBuffer(data, address, len);
        AddObject(obj);
    }

    //向线程增加命令字
    public void AddObject(Object obj)
    {
        synchronized(list)
        {
            list.add(obj);
        }
    }

    //在线程命令字队列前插入命令字
    public void InsertObject(Object obj)
    {
        synchronized(list)
        {
            list.add(0, obj);
        }
    }

    private Object GetObject()
    {
        if (list.size() > 0)
        {
            Object obj;
            synchronized(list)
            {
                obj = list.get(0);
                list.remove(obj);
            }
            return obj;
        }
        return null;
    }

}